<!-- 
 * 菜单管理
 * @author: 冯宇
 * @since: 2022-04-13
 * index.vue
-->
<template>
  <div class="menu-manage-container h100">
    <div class="content-left">
      <div class="content-title-left">菜单树</div>
      <el-tree :data="data.dataSource" node-key="id" :default-expand-all="false" :expand-on-click-node="false"
        :highlight-current="true" draggable @node-drag-end="handleDragEnd" :allow-drop="allowDrop"
        :default-expanded-keys="data.activeKey">
        <template #default="{ data }">
          <span class="custom-tree-node">
            <span @click="showDetail(data)" :style="{ fontWeight: data.parentid == 1 ? 700 : 400 }">{{ data.menucn
            }}</span>
            <span class="icon" @click="addMenu(data)">
              <i class="iconfont icon-zengjiatianjiajiahao"></i>
            </span>
            <span class="icon" @click="delMenu(data)" v-if="data.parentid != '1'">
              <i class="iconfont icon-shanchu"></i>
            </span>
          </span>
        </template>
      </el-tree>
    </div>

    <div class="content-right">
      <div class="content-title-right">{{ data.title }}菜单</div>
      <table class="right-table" @mouseover="tableOver(0, $event)" @mouseout="tableOver(1, $event)">
        <tr class="table-tr">
          <td class="table-title">上级菜单</td>
          <td class="table-text">
            <el-input disabled v-model="data.menuTable.parentname" @focus="tableOver(2, $event)"
              @blur="tableOver(3, $event)" />
          </td>
        </tr>
        <tr class="table-tr">
          <td class="table-title">菜单名称</td>
          <td class="table-text">
            <el-input v-model="data.menuTable.menucn" @focus="tableOver(2, $event)" @blur="tableOver(3, $event)" />
          </td>
        </tr>
        <tr class="table-tr">
          <td class="table-title">路由名称</td>
          <td class="table-text">
            <el-input v-model="data.menuTable.name" @focus="tableOver(2, $event)" @blur="tableOver(3, $event)" />
          </td>
        </tr>
        <tr class="table-tr">
          <td class="table-title">菜单路径</td>
          <td class="table-text">
            <el-input v-model="data.menuTable.href" @focus="tableOver(2, $event)" @blur="tableOver(3, $event)" />
          </td>
        </tr>
        <tr class="table-tr">
          <td class="table-title">路由地址</td>
          <td class="table-text">
            <el-input v-model="data.menuTable.path" @focus="tableOver(2, $event)" @blur="tableOver(3, $event)" />
          </td>
        </tr>
        <tr class="table-tr">
          <td class="table-title">菜单图标</td>
          <td class="table-text">
            <i :class="data.menuTable.icon"></i>
          </td>
        </tr>
        <tr class="icon-list" @click="checkMenuIcon($event)">
          <i v-for="(menuIcon, iconI) in data.iconArr" :key="'icon' + iconI"
            :class="'iconfont icon-' + menuIcon.font_class"></i>
        </tr>
      </table>

      <div class="right-bottom">
        <div class="title">是否有效：</div>
        <div class="content">
          <el-radio v-model="data.menuTable.valid" :label="true">是</el-radio>
          <el-radio v-model="data.menuTable.valid" :label="false">否</el-radio>
        </div>
      </div>
      <div class="right-bottom">
        <el-button type="primary" :disabled="data.id == 1" @click="saveMenu" v-if="data.saveOrEdit">保存</el-button>
        <el-button type="primary" @click="saveAddModify" v-if="!data.saveOrEdit">添加菜单</el-button>
      </div>
    </div>
  </div>
</template>

<script setup >
import { reactive, computed, inject } from 'vue'
import { getMenuListApi, addMenuApi, editMenuApi, delMenuApi, sortMenuApi } from '@/api/interface/menu.js'
import { ElMessageBox, ElMessage } from 'element-plus'
import icon from '@/assets/fonts/yunnan-iconfont/iconfont.json'

import { useRouter } from 'vue-router'
import { useStore } from 'vuex'
const router = useRouter()
const store = useStore()

const reload = inject('reload')
const data = reactive({
  dataSource: [],
  menuTable: {
    parentname: '',
    menucn: '',
    name: '',
    href: '',
    path: '',
    icon: '',
    valid: true,
    id: '',
    parentid: '',
  },
  id: '0',
  saveOrEdit: true,
  title: '编辑',
  iconArr: computed(() => icon.glyphs),
  sortid: 1,
  activeKey: [],
})

//展示菜单详情
const showMenuDetail = (currentMenu) => {
  data.menuTable.parentname = currentMenu.parentname
  data.menuTable.menucn = currentMenu.menucn
  data.menuTable.name = currentMenu.name
  data.menuTable.href = currentMenu.href
  data.menuTable.path = currentMenu.path
  data.menuTable.icon = currentMenu.icon
  data.menuTable.valid = currentMenu.valid
  data.menuTable.id = currentMenu.id
  data.menuTable.parentid = currentMenu.parentid
}
//初始化处理菜单树
const initializeMenu = (list, parentname) => {
  let menu = []
  if (list.length > 0) {
    menu = list.map((item) => {
      item.children = item.childresource
      item.parentname = parentname
      initializeMenu(item.childresource, item.menucn)
      return item
    })
  }
  return menu
}
//获取菜单列表并渲染
const initializeMenuList = () => {
  getMenuListApi().then((res) => {
    const menuList = res.data[0].childresource
    const newMenu = initializeMenu(menuList, res.data[0].menucn)
    data.dataSource = newMenu
    showMenuDetail(menuList[0])
  })
}
initializeMenuList()
//表格交互效果
const tableOver = (i, e) => {
  switch (i) {
    case 0:
      if (e.target.nodeName === 'INPUT') {
        e.target.closest('td').style.backgroundColor = '#f6f6f6'
        e.target.style.backgroundColor = '#f6f6f6'
      }
      break
    case 1:
      if (e.target.nodeName === 'INPUT') {
        e.target.closest('td').style.backgroundColor = '#fff'
        e.target.style.backgroundColor = '#fff'
      }
      break
    case 2:
      e.target.closest('td').style.border = '1px solid #2e92fa'
      break
    case 3:
      e.target.closest('td').style.backgroundColor = '#fff'
      e.target.closest('td').style.border = '1px solid #e3e3e3'
      e.target.style.backgroundColor = '#fff'
      break
    default:
      break
  }
}
//查看子菜单
const showDetail = (nodeData) => {
  showMenuDetail(nodeData)
  data.title = '编辑'
  data.saveOrEdit = true
}




//不允许跨层级拖拽
const allowDrop = (draggingNode, dropNode, type) => {
  return type != 'inner' && draggingNode.data.parentid == dropNode.data.parentid
}
//拖拽排序
const handleDragEnd = (draggingNode, dropNode, dropType, ev) => {
  if (draggingNode == dropNode) return
  let start = 1
  const newSortId = (arr) => {
    arr.forEach(v => {
      v.sortid = start++
    })
    arr.forEach(v => {
      if (v.children) {
        newSortId(v.children)
      }
    })
  }
  newSortId(data.dataSource)
  // console.log(data.dataSource,'重新排序');
  let sortArr = []
  const sort = (arr) => {
    arr.forEach(v => {
      let obj = {
        id: v.id,
        sortid: v.sortid
      }
      sortArr.push(obj)
      if (v.children) sort(v.children)
    })
  }
  sort(data.dataSource)
  // console.log(sortArr,'sortid');
  // return
  sortMenuApi(JSON.stringify(sortArr)).then(res => {
    if (res.status === 200) {
      ElMessage({
        message: res.message,
        type: 'success',
      })
      sessionStorage.keyIdArr = JSON.stringify([+draggingNode.data.parentid])
      initializeMenuList()
      data.activeKey = JSON.parse(sessionStorage.keyIdArr)
      sessionStorage.removeItem('keyIdArr')
    }
  })
}





//点击新增
const addMenu = (item) => {
  data.saveOrEdit = false
  data.title = '添加'
  data.menuTable.href = ''
  data.menuTable.icon = ''
  data.menuTable.menucn = ''
  data.menuTable.name = ''
  data.menuTable.parentid = item.id
  data.menuTable.parentname = item.menucn
  data.menuTable.path = ''
  data.menuTable.valid = true
}
//点击删除
const delMenu = (item) => {
  ElMessageBox.confirm('是否删除该菜单?').then(() => {
    delMenuApi({ id: item.id }).then((res) => {
      if (res.status === 200) {
        ElMessage({
          message: res.message,
          type: 'success',
        })
        initializeMenuList()
      }
    })
  })
}
//更改菜单图标
const checkMenuIcon = (e) => {
  if (e.target.nodeName == 'I') {
    data.menuTable.icon = e.target.className
  }
}
//保存编辑
const saveMenu = () => {
  ElMessageBox.confirm('是否保存菜单更改?')
    .then(() => {
      const params = {
        href: data.menuTable.href,
        icon: data.menuTable.icon,
        menucn: data.menuTable.menucn,
        name: data.menuTable.name,
        parentid: data.menuTable.parentid,
        parentname: data.menuTable.parentname,
        path: data.menuTable.path,
        valid: data.menuTable.valid,
        id: data.menuTable.id,
      }
      editMenuApi(JSON.stringify(params)).then(async (res) => {
        if (res.status === 200) {
          ElMessage({
            message: res.message,
            type: 'success',
          })
          reload()
          await store.dispatch('user/getMenuList')
          await store.dispatch('routes/setAllRoutes').then((res) => {
            res.forEach((item) => {
              router.addRoute(item)
            })
          })
        }
      })
    })
    .catch(() => {
      ElMessage({
        message: '已取消',
        type: 'warning',
      })
      initializeMenuList()
    })
}
//提交新增
const saveAddModify = () => {
  ElMessageBox.confirm('确认新增此菜单?')
    .then(() => {
      const params = {
        parentname: data.menuTable.parentname,
        parentid: data.menuTable.parentid,
        menucn: data.menuTable.menucn,
        name: data.menuTable.name,
        href: data.menuTable.href,
        path: data.menuTable.path,
        valid: data.menuTable.valid,
        icon: data.menuTable.icon,
      }
      addMenuApi(JSON.stringify(params)).then((res) => {
        if (res.status === 200) {
          data.saveOrEdit = true
          data.title = '编辑'
          initializeMenuList()
          ElMessage({
            message: res.message,
            type: 'success',
          })
        }
      })
    })
    .catch(() => {
      ElMessage({
        message: '已取消',
        type: 'warning',
      })
    })
}
</script>

<style lang="scss" scoped>
.menu-manage-container {
  display: flex;
  padding: 20px;
  box-sizing: border-box;

  .content-left {
    width: 300px;
    background-color: #fff;
    overflow-y: scroll;
    border-radius: 8px;
    margin-right: 20px;

    .content-title-left {
      margin-bottom: 10px;
      font-weight: 700;
      color: #333;
    }

    .custom-tree-node {
      display: flex;
      align-items: center;

      .icon {
        opacity: 0;
        margin-left: 20px;
        color: #00a2ff;
        line-height: 12px;
        transition: all 0.3s;
      }
    }

    ::v-deep .el-tree-node__content {
      height: 36px;
      font-size: 14px;
    }

    ::v-deep .el-tree-node__content:hover .icon {
      opacity: 1;
    }

    ::v-deep .el-tree-node__expand-icon {
      font-size: 16px;
    }
  }

  .content-right {
    flex: 1;
    overflow-y: scroll;

    .content-title-right {
      margin-bottom: 16px;
      font-weight: 700;
      color: #333;
    }

    .right-table {
      width: 100%;
      border-collapse: collapse;

      tr {
        display: flex;
        width: 100%;

        td {
          border: 1px solid #e3e3e3;
          transition: 0.3s;
          box-sizing: content-box;
        }

        .table-title {
          height: 50px;
          line-height: 50px;
          width: 180px;
          background: #f5f7fd;
          text-align: center;
          font-weight: 700;
          font-size: 14px;
          box-sizing: border-box;
          color: #333;
        }

        .table-text {
          display: flex;
          align-items: center;
          flex: 1;
          transition: all 0.3s;

          i {
            background-color: #fff;
            font-size: 20px;
            margin-left: 20px;
          }

          ::v-deep .el-input__inner {
            color: #333;
            padding-left: 20px;
            box-shadow: none;
            transition: all 0.3s;
          }
        }

        .table-text-icon {
          flex: 1;
          height: 50px;
          line-height: 50px;
        }
      }

      ::v-deep .el-input__inner {
        background-color: white;
      }
    }

    .icon-list {
      width: 100%;
      flex-wrap: wrap;
      height: 100px;
      padding: 6px;
      overflow-y: scroll;
      border: 1px solid #e3e3e3;
      box-sizing: border-box;

      i {
        font-size: 20px;
        width: 20px;
        height: 20px;
        padding: 10px;
        background-color: #fff;
        transition: all 0.3s;
      }

      i:hover {
        background-color: #eee;
        cursor: pointer;
      }
    }

    .right-bottom {
      display: flex;
      align-items: center;
      margin-top: 12px;

      .title {
        font-weight: 700;
      }

      .content {
        margin-left: 20px;
      }
    }
  }
}
</style>
